package com.gylang.im.core.enums;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.gylang.commons.util.CollectionUtils;
import com.gylang.im.core.exception.BaseException;
import com.gylang.im.core.exception.BizException;
import com.gylang.im.core.exception.ValidateException;
import com.gylang.im.core.myassert.EnumAssert;
import org.apache.commons.lang3.StringUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */

public interface BaseEnum extends EnumAssert {

    /**
     * 状态码
     *
     * @return 状态码
     */
    String getCode();

    /**
     * 状态信息
     *
     * @return 状态码
     */
    String getMsg();


    /**
     * 参数校验
     */
    @Override
    default void asThrow() {
        throw new ValidateException(this.getCode(), this.getMsg());
    }

    /**
     * boolean判断
     *
     * @param b boolean
     */
    default void asTrue(boolean b, String... msg) {
        if (!b) {
            throw new ValidateException(this.getCode(), castToMsg(msg));
        }
    }

    /**
     * boolean判断
     *
     * @param b boolean
     */
    default void asTrue(BooleanSupplier b, String... msg) {
        if (!b.getAsBoolean()) {
            throw new ValidateException(this.getCode(), castToMsg(msg));
        }
    }

    /**
     * 业务层异常
     */
    @Override
    default void bizException() {
        throw new BizException(this.getCode(), this.getMsg());

    }


    /**
     * 其他类型异常
     *
     * @param t   异常类型
     * @param <T> 异常类性
     */
    default <T extends BaseException> void otherException(Class<T> t) {
        try {
            BaseException baseException = t.newInstance();
            baseException.setCode(this.getCode());
            baseException.setMsg(this.getMsg());
            throw baseException;
        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }

    /**
     * 参数校验
     *
     * @param msg 异常信息
     */
    default void validException(String... msg) {
        throw new BizException(this.getCode(), castToMsg(msg));
    }

    /**
     * 空校验 并抛出错误
     *
     * @param data 校验类型
     * @param msg  msg
     * @param <T>  类型
     */
    default <T> void asNotEmpty(T data, String... msg) {
        if (ObjectUtil.isEmpty(data)) {
            throw new BizException(this.getCode(), castToMsg(msg));
        }
    }



    /**
     * 对集合进行判断
     *
     * @param data 集合数据
     * @param msg  返回信息
     */
    default void asNotEmpty(Collection<?> data, String... msg) {
        if (CollectionUtils.isNotEmpty(data)) {
            throw new BizException(this.getCode(), castToMsg(msg));
        }
    }

    /**
     * 对集合进行判断
     *
     * @param data 集合数据
     * @param msg  返回信息
     */
    default void asAllNotEmpty(String msg, Object... data) {
        if (!ObjectUtil.isAllNotEmpty(data)) {
            throw new BizException(this.getCode(), msg);
        }
    }

    /**
     * 对集合进行判断
     *
     * @param data 集合数据
     * @param msg  返回信息
     */
    default void asNotAllEmpty(String msg, Object... data) {
        if (ObjectUtil.isAllEmpty(data)) {
            throw new BizException(this.getCode(), msg);
        }
    }

    /**
     * 对集合进行判断
     *
     * @param obj   集合数据
     * @param group 条件判断组 设值group属性 会在符合条件下才会判断
     */
    default void valid(Object obj, Class<?>... group) {
        Set<ConstraintViolation<Object>> validMsg = validator.validate(obj, group);
        checkValid(validMsg);
    }

    /**
     * 对集合进行判断
     *
     * @param obj          集合数据
     * @param propertyName 判断实体类属性名
     */
    default void validProperty(Object obj, String... propertyName) {
        Set<ConstraintViolation<Object>> errorMsg = new LinkedHashSet<>();
        for (String name : propertyName) {
            errorMsg.addAll(validator.validateProperty(obj, name));
        }
        checkValid(errorMsg);
    }

    default void checkValid(Set<ConstraintViolation<Object>> validMsg) {
        if (!validMsg.isEmpty()) {
            String errorMsg = validMsg.stream()
                    .map(ConstraintViolation::getMessage)
                    .collect(Collectors.joining(","));
            throw new ValidateException(this.getCode(), errorMsg);
        }
    }


    /**
     * 抛出基于BaseException的异常
     *
     * @param exception 异常类型
     * @param msg       返回信息
     */
    default <T extends BaseException> void baseException(Class<T> exception, String... msg) {

        try {
            BaseException baseException = exception.newInstance();
            baseException.setCode(this.getCode());
            baseException.setMsg(castToMsg(msg));
            throw baseException;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 转成错误提示语
     */
    default String castToMsg(String... msg) {
        if (ArrayUtil.isEmpty(msg)) {
            return this.getMsg();
        } else {
            return StringUtils.join(msg, ",");
        }
    }

    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
//    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
}
